/*
 * Mesh.h
 *
 *  Created on: 17 mars 2011
 *      Author: seeme
 */

#ifndef MESH_H_
#define MESH_H_
#include "../../../Tools/Geometry/Point.h"
#include "../../../Tools/Geometry/Triangle.h"
#include "../../../LogManager/Log.hpp"
#include "../../../Tools/Geometry/Vect4.h"
#include "../Textures/Texture.h"
#include "../TextBased/AbstractXMLResource.h"
#include "../TextBased/Shaders/Program.h"
#include <GL/glew.h>


#include "../../../Scene/Materials/Material.h"

class Mesh: public AbstractXMLResource{

public:
	Mesh(std::string name, std::vector<Point> points, std::vector<Triangle<unsigned int> > tri, Material* material): AbstractXMLResource(name, ""),
	m_points(points), m_triangles(tri), m_programs(), m_material(material), m_texture(NULL){m_vertice = NULL; m_normals = NULL; m_index = NULL;
	m_uv = NULL;
	};

	Mesh(std::string name, std::string filename): AbstractXMLResource(name, filename), m_programs(), m_material(NULL), m_texture(NULL), m_uv(NULL){};

	Mesh():m_points(), m_triangles(), m_vertice(NULL), m_normals(NULL), m_index(NULL), m_programs(),
			m_material(NULL), m_texture(NULL), m_uv(NULL){};

	~Mesh(){
		Log::i("Mesh") << "Deleting";
		/*delete m_vertice;
		delete m_normals;
		delete m_index;

		delete m_texture;

		delete m_uv;
		delete m_material;*/}

	friend std::ostream& operator<<(std::ostream& out, const Mesh& m){
		m.print(out);
		return out;
	}

	virtual void print(std::ostream& o) const {
		o << "Mesh: " << " " << m_name << " " << m_points.size() << " " << m_triangles.size();
	}

	GLfloat* getCoordTab();
	GLuint getCoordTabSize();

	GLfloat* getNormTab();
	GLuint getNormTabSize();

	GLfloat* getUvTab();
	GLuint getUvTabSize();

	std::string getModelName(){return m_name;}

	GLuint* getIndexTab();
	GLuint getIndexTabSize();

	size_t getSize(){return m_size;};

	bool create(){loadFromFile(); return true;};
	void destroy();

	GLuint getProgId();

	Material* getMaterial();

	void sendMaterial(GLuint program);
	void sendTexture(GLuint program);

	GLuint getProgramId(const char* name){return getProgramId(std::string(name));}
	GLuint getProgramId(std::string name);

	void setTexture(Texture* tex){m_texture = tex;}

	void addProgram(std::string name, Program* prog);
protected:

	void loadFromFile();

	std::vector<Point> m_points;
	std::vector<Triangle<unsigned int> > m_triangles;

	GLfloat* m_vertice;
	GLfloat* m_normals;
	GLuint* m_index;


	std::map<std::string, GLuint> m_programs;

	//Les propriétés du matériau
	Material* m_material;
	Texture* m_texture;

	GLfloat* m_uv;
};
#endif /* MESH_H_ */
